//
//  DBCustomButton.swift
//  DBCA
//
//  Created by mugua on 2024/7/3.
//

import UIKit

class DBCustomButton: UIButton {

    enum Style: Int {
        case titleLeftImageRight
        case titleRightImageLeft
        case titleTopImageBottom
        case titleBottomImageTop
        case titleMiddleImageTwoSide
    }

    @IBInspectable var space: CGFloat = 3
    
    private lazy var rightImageView: UIImageView = {
        let imgView = UIImageView()
        return imgView
    }()

    var style = Style.titleLeftImageRight

    @available(*, unavailable, message: "This property is reserved for Interface Builder. Use 'style' instead.")
    @IBInspectable var styleAdapter: Int {
        get {
            return self.style.rawValue
        }
        set {
            self.style = Style(rawValue: newValue) ?? .titleLeftImageRight
        }
    }

    private func layoutVertical(topView: UIView?, bottomView: UIView?) {
        if var topViewFrame = topView?.frame,
            var bottomViewFrame = bottomView?.frame {
            let verticalHeight = topViewFrame.height + space + bottomViewFrame.height
            topViewFrame.origin = CGPoint(x: (frame.width - topViewFrame.width) / 2, y: (frame.height - verticalHeight) / 2)
            topView?.frame = topViewFrame
            bottomViewFrame.origin = CGPoint(x: (frame.width - bottomViewFrame.width) / 2, y: (frame.height - bottomViewFrame.height + space + topViewFrame.height) / 2)
            bottomView?.frame = bottomViewFrame
        }
    }

    private func layoutHorizontal(leftView: UIView?, rightView: UIView?) {
        if var leftViewFrame = leftView?.frame,
            var rightViewFrame = rightView?.frame {
            if (leftView?.isHidden).value {
                leftViewFrame.size = CGSize.zero
            } else if (rightView?.isHidden).value {
                rightViewFrame.size = CGSize.zero
            }
            let horizontalWidth = leftViewFrame.width + space + rightViewFrame.width
            leftViewFrame.origin = CGPoint(x: (frame.width - horizontalWidth) / 2, y: (frame.height - leftViewFrame.height) / 2)
            leftView?.frame = leftViewFrame
            rightViewFrame.origin = CGPoint(x: (frame.width - rightViewFrame.width + space + leftViewFrame.width) / 2, y: (frame.height - rightViewFrame.height) / 2)
            rightView?.frame = rightViewFrame
        }
    }

    
    private func layoutHorizontal(leftView: UIView?, rightView: UIView?, middleView: UIView?) {
        if var leftViewFrame = leftView?.frame,
           var rightViewFrame = rightView?.frame,
           var middleViewFrame = middleView?.frame {
            if (leftView?.isHidden).value {
                leftViewFrame.size = CGSize.zero
            } else if (rightView?.isHidden).value {
                rightViewFrame.size = CGSize.zero
            } else if (middleView?.isHidden).value {
                middleViewFrame.size = CGSize.zero
            }
            let horizontalWidth = leftViewFrame.width + rightViewFrame.width + middleViewFrame.width
            leftViewFrame.origin = CGPoint(x: (frame.width - horizontalWidth) / 2, y: (frame.height - leftViewFrame.height) / 2)
            leftView?.frame = leftViewFrame
            middleViewFrame.origin = CGPoint(x: leftViewFrame.width + leftViewFrame.origin.x + space, y: (frame.height - middleViewFrame.height) / 2)
            middleView?.frame = middleViewFrame
            rightViewFrame.origin = CGPoint(x: middleViewFrame.width + middleViewFrame.origin.x + space, y: (frame.height - rightViewFrame.height) / 2 )
            rightView?.frame = rightViewFrame
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        imageView?.sizeToFit()
        titleLabel?.sizeToFit()
        switch style {
        case .titleLeftImageRight:
            layoutHorizontal(leftView: titleLabel, rightView: imageView)
        case .titleRightImageLeft:
            layoutHorizontal(leftView: imageView, rightView: titleLabel)
        case .titleBottomImageTop:
            layoutVertical(topView: imageView, bottomView: titleLabel)
        case .titleTopImageBottom:
            layoutVertical(topView: titleLabel, bottomView: imageView)
        case .titleMiddleImageTwoSide:
            addSubview(rightImageView)
            if rightImageView.frame.isNull {
                layoutHorizontal(leftView: imageView, rightView: titleLabel)
            } else {
                layoutHorizontal(leftView: imageView, rightView: rightImageView, middleView: titleLabel)
            }
        }
    }

    override func setImage(_ image: UIImage?, for state: UIControl.State) {
        super.setImage(image, for: state)
        setNeedsLayout()
    }

    override func setTitle(_ title: String?, for state: UIControl.State) {
        super.setTitle(title, for: state)
        setNeedsLayout()
    }

    override var intrinsicContentSize: CGSize {
        imageView?.sizeToFit()
        titleLabel?.sizeToFit()

        let labelFrameOrNil = titleLabel?.frame
        let imageFrameOrNil = imageView?.frame

        if labelFrameOrNil.isNil && imageFrameOrNil.isNil {
            return super.intrinsicContentSize
        }
        guard let labelFrame = labelFrameOrNil else {
            return CGSize(width: imageFrameOrNil!.width, height: imageFrameOrNil!.height)
        }
        guard let imageFrame = imageFrameOrNil else {
            return CGSize(width: labelFrameOrNil!.width, height: labelFrameOrNil!.height)
        }

        switch style {
        case .titleLeftImageRight, .titleRightImageLeft:
            return CGSize(width: labelFrame.width + space + imageFrame.width, height: imageFrame.height)
        case .titleBottomImageTop, .titleTopImageBottom:
            return CGSize(width: imageFrame.width, height: imageFrame.height + space + labelFrame.height)
        case .titleMiddleImageTwoSide:
            if rightImageView.frame.isNull {
                
                return CGSize(width: labelFrame.width + space + imageFrame.width, height: imageFrame.height)
            }
            return CGSize(width: labelFrame.width + 4 * space + imageFrame.width + rightImageView.frame.width, height: imageFrame.height)
        }
    }

    func setRightImage(with image: UIImage) {
        rightImageView.image = image
        rightImageView.size = imageView?.size ?? CGSize(width: 12, height: 12)
        setNeedsLayout()
    }
}
